package com.zeng.generate.code.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.zeng.generate.code.callback.*;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

public class ExportExcelUtil {

    public static ExcelWriter excelExport(String fileName, List<?> dataList, ExportCallBack exportCallBack, ExportImageCallBack exportImageCallBack){
        String path = "E:/temp/excel/"+ fileName +"-"+ DateUtil.format(new Date(), "yyyyMMddHHmmssSSS") +".xls";

        ExcelWriter writer = ExcelUtil.getWriter(path); // 通过工具类创建writer
        exportCallBack.process(writer); // 设置标题，行列样式处理

        writer.write(dataList); // 插入数据
        writer.getSheet().setDefaultColumnWidth(15); // 默认列宽
        writer.getOrCreateRow(0).setHeightInPoints(30); // 默认标题行高

        if (exportImageCallBack != null) {
            exportImageCallBack.process(writer); // 插入图片处理
        }
        return writer;
    }

    /**
     * 所有数据导出
     * @param dataList 数据列表
     * @param exportCallBack 添加标题
     * @param exportImageCallBack 图片处理 为null不导出图片
     * @return
     */
    public static ExcelWriter excelDownload(List<?> dataList, ExportCallBack exportCallBack, ExportImageCallBack exportImageCallBack){
        ExcelWriter writer = ExcelUtil.getWriter(); // 通过工具类创建writer
        exportCallBack.process(writer); // 设置标题，行列样式处理

        if (dataList != null && !dataList.isEmpty()) {
            writer.write(dataList); // 插入数据
            writer.getSheet().setDefaultColumnWidth(15); // 默认列宽
            writer.getOrCreateRow(0).setHeightInPoints(30); // 默认标题行高

            if (exportImageCallBack != null) {
                exportImageCallBack.process(writer); // 插入图片处理
            }
        }
        return writer;
    }

    /**
     * sheet分页导出，单回调方式
     * @param dataList 数据列表
     * @param row 单页行数
     * @param exportCallBack 添加标题
     * @param exportStyleCallBack 表格样式处理
     * @param exportImagePageCallBack 图片处理 为null不导出图片
     * @return
     */
    public static ExcelWriter excelPageDownload(List<?> dataList, int row, ExportCallBack exportCallBack,
                                                ExportStyleCallBack exportStyleCallBack,
                                                ExportImagePageCallBack exportImagePageCallBack){
        ExcelWriter writer = ExcelUtil.getWriter(); // 通过工具类创建writer
        exportCallBack.process(writer); // 设置标题，行列样式处理

        if (dataList != null && !dataList.isEmpty()) {
            int totalPage = PageUtil.totalPage(dataList.size(), row);

            for (int i = 1; i <= totalPage; i++) {
                List<?> pageList = CommonUtil.pageList(dataList, i, row);
                writer.setSheet("sheet"+ i).write(pageList); // 插入数据

                exportStyleCallBack.process(writer);

                if (exportImagePageCallBack != null) {
                    exportImagePageCallBack.process(writer, pageList); // 插入图片处理
                }
            }
        }
        return writer;
    }

    /**
     * sheet分页导出，全回调方式
     * @param dataList 数据列表
     * @param row 单页行数
     * @param exportCallBack
     * @return
     */
    public static ExcelWriter excelPageDownload(List<?> dataList, int row, ExportCallBackAll exportCallBack){
        ExcelWriter writer = ExcelUtil.getWriter(); // 通过工具类创建writer
        exportCallBack.addHeaderAlias(writer); // 设置标题，行列样式处理

        if (dataList != null && !dataList.isEmpty()) {
            int totalPage = PageUtil.totalPage(dataList.size(), row);

            for (int i = 1; i <= totalPage; i++) {
                List<?> pageList = CommonUtil.pageList(dataList, i, row);
                writer.setSheet("sheet"+ i).write(pageList); // 插入数据

                exportCallBack.sheetStyle(writer);

                if (exportCallBack != null) {
                    exportCallBack.imageProcess(writer, pageList); // 插入图片处理
                }
            }
        }
        return writer;
    }

    public static void defaultStyle(ExcelWriter writer){
        //设置水平对齐的样式为居中对齐;
        writer.getCellStyle().setAlignment(HorizontalAlignment.CENTER);
        //设置垂直对齐的样式为居中对齐;
        writer.getCellStyle().setVerticalAlignment(VerticalAlignment.CENTER);
        writer.getCellStyle().setWrapText(true);

        writer.getSheet().setDefaultColumnWidth(15); // 默认列宽
        writer.getOrCreateRow(0).setHeightInPoints(30); // 默认标题行高
    }

    /**
     * Excel 插入图片（xls格式）
     * @param writer ExcelWriter
     * @param patriarch HSSFPatriarch
     * @param imagePath 图片地址
     * @param row 行
     * @param column 列
     */
    public static void createImage(ExcelWriter writer, HSSFPatriarch patriarch, String imagePath, String imageType,
                                   int row, short column){
        if (writer == null) {
            return;
        }

        try {
            row = row + 1;
            if (StrUtil.isEmpty(imagePath)) {
                writer.getOrCreateRow(row).setHeightInPoints(30);
            } else {
                File file = new File(imagePath);
                if (FileUtil.exist(file)) {
                    writer.getOrCreateRow(row).setHeightInPoints(150);

                    ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
                    ImageIO.write(ImageIO.read(file), imageType, byteArrayOut);

                    // anchor主要用于设置图片的属性
                    HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, column, row, column, row);
                    anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);

                    int picture = "jpg".equals(imageType) ? XSSFWorkbook.PICTURE_TYPE_JPEG : XSSFWorkbook.PICTURE_TYPE_PNG;
                    int pictureIdx = writer.getWorkbook().addPicture(byteArrayOut.toByteArray(), picture);

                    // 插入图片
                    patriarch.createPicture(anchor, pictureIdx);
                } else {
                    writer.getOrCreateRow(row).setHeightInPoints(30);
                }
            }
        } catch (IOException e) {
            StaticLog.info(e.getMessage(), e);
        } catch (Exception e) {
            StaticLog.info(e.getMessage(), e);
        }
    }

    public static void main(String[] args) {
        String path = "E:\\temp\\excel\\UserTepl.xls";
        ExcelWriter writer = ExcelUtil.getWriter(path); // 通过工具类创建writer
        // 准备下拉列表数据
        String[] optionArr = new String[]{"A","B","C","D"};

        // 设置第一列的1-10000行为下拉列表
        CellRangeAddressList regions = new CellRangeAddressList(1, 10000, 0, 0);
        // 创建下拉列表数据
        DVConstraint constraint = DVConstraint.createExplicitListConstraint(optionArr);
        // 绑定
        HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
        writer.addValidationData(dataValidation);
        writer.close();
    }

}
